<template>
  <div class="switch-page" 
       v-loading="loading" 
       :element-loading-text="loadingText">
    <div class="switch-left column">
      <el-form :model="equipForm" style="width:100%;padding:1rem;padding-bottom:.5rem;" label-width="70px" :rules="equipFormRules" ref="searchForm">
        <div class="between center" style="margin-bottom:10px;">
          <span>设置搜索查询</span>
        </div>
        <el-form-item label="串口" prop="portModel">
          <el-select v-model="equipForm.portModel" placeholder="请选择" size="small" style="width:100%;">
            <el-option
              v-for="item in portList"
              :key="item.value"
              :label="item.label"
              :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-row>
          <el-col :span="24">
            <el-form-item label="波特率" prop="rateModel">
              <el-select v-model="equipForm.rateModel" placeholder="请选择" size="mini" class="select">
                <el-option
                  v-for="(item,index) in rate"
                  :key="index"
                  :label="item"
                  :value="item">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
       <el-form-item label="范围" required>
        <el-col :span="11">
          <el-form-item prop="start">
            <el-input v-model.number="equipForm.start" placeholder="请输入" size="small" class="select"></el-input>
          </el-form-item>
         </el-col>
        <el-col class="line" :span="2">-</el-col>
        <el-col :span="11">
          <el-form-item prop="end">
            <el-input v-model.number="equipForm.end" placeholder="请输入" size="small" class="select"></el-input>
          </el-form-item>
        </el-col>
       </el-form-item>
       <div class="row-center">
         <el-button size="small" type="primary" style="width:90%;" @click="rulesValide">查询设备</el-button>
       </div>
      </el-form>
      <div style="overflow:auto;" class="expand">
        <equip-list :equipList="equipList" @chooseEquip="chooseEquip" @chooseEquips="chooseEquips" @clearEquipList="()=>{equipList=[]}"></equip-list>
      </div>
    </div>
    <div class="switch-right" v-if="editConfig">
      <div class="between center" style="padding-bottom:.5rem;">
        <div class="center">
          <span style="font-size:1.2rem;margin-right:1rem;">配置</span>
          <!-- <span style="font-size:1.2rem;">使用已有配置</span> -->
          <span style="margin-right:1rem;background: #F7F7F9;border-radius: 4px;padding:.5rem 1rem;">{{chooseConfigName}}</span>
          <el-button type="primary" size="small" @click="chooseConfig">选择配置</el-button>
        </div>
      </div>

      <div v-if="JSON.stringify(config) !== '{}'">
        <div class="center between" style="margin-bottom:15px;">
          <el-form :inline="true" class="no-error-form">
            <el-form-item label="波特率">
              <el-select v-model.number="config.paramArr[2]" placeholder="请选择" size="small" class="select" style="max-width:150px;">
                <el-option
                  v-for="(item,index) in rateList"
                  :key="index"
                  :label="item"
                  :value="index">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="ID号">
              <el-input size="small" v-model.number="eid" style="max-width:150px;" :disabled="true"></el-input>
            </el-form-item>
            <el-form-item label="自动上报">
              <el-checkbox class="select" v-model.number="config.paramArr[3]" :true-label="1" :false-label="0"></el-checkbox>
            </el-form-item>
            <el-form-item label="背光开">
              <el-checkbox class="select" v-model.number="config.paramArr[4]" :true-label="1" :false-label="0"></el-checkbox>
            </el-form-item>
          </el-form>
          <div>
            SN: {{chooseSn.join('')}}
            设备固件版本号:{{config.paramArr[0]}}
          </div>
        </div>
        <config-right :config="config" @delConfig="delConfig" @confirmConfig="confirmConfig"></config-right>
      </div>
      <div v-else class="center row-center" style="padding:5rem;border:1px solid #ebebeb;margin-top:2rem;">请选择设备</div>
      <div style="display:flex;justify-content:center;margin-top:2rem;">
          <el-button type="primary" size="small" plain style="margin-right:4rem;" @click="downloadTo(eid,false)">下载配置</el-button>
          <el-button type="primary" size="small" @click="downloadConfig">保存配置</el-button>
          <!-- <el-button type="primary" size="small" @click="downloadTos">批量下载配置</el-button> -->
        </div>
    </div>

    <div class="switch-right" v-if="!editConfig">
      <el-page-header @back="editConfig=true" content="配置页面" style="margin-bottom:.8rem;">
      </el-page-header>
      <div class="header">
        <div style="font-size:1.2rem;">使用已有配置</div>
        <el-form class="center between" style="width:100%;padding:1rem 0;" label-width="50px" :inline="true" label-position="left">
          <div class="center">
            <el-form-item label="搜索:" style="margin-bottom:0;margin-right:2rem;">
              <el-input v-model="configName" size="small" placeholder="请输入关键字"></el-input>
            </el-form-item>
            <el-checkbox v-model="all" true-label="0" false-label="1" @change="getConfigList" style="margin-right:1rem;">只看自己</el-checkbox>
            <!-- <el-button type="danger" plain size="small">重置</el-button>
            <el-button type="primary" size="small">查询</el-button> -->
          </div>
          <el-button type="primary" size="small" @click="editConfig=true">新增配置</el-button>
        </el-form>
      </div>
      <div class="expand">
        <config-list :configList="filterConfigList" @getConfigList="getConfigList" @changeConfig="changeConfig"></config-list>
      </div>
    </div>
  </div>
</template>


<script>
import EquipList from './children/EquipList'
import ConfigList from './children/ConfigList'
import ConfigRight from './children/ConfigRight'
import Bus from '../../utils/bus.js'
export default {
  components:{
    EquipList,ConfigList,ConfigRight
  },
  data(){
    return {
      equipFormRules:{
          portModel: [
            { required: true, message: '请选择串口', trigger: 'change' },
          ],
          rateModel: [
            { required: true, message: '请选择波特率', trigger: 'change' },
          ],
          start: [
            { required: true, message: '请输入范围', trigger: 'blur' },
          ],
          end: [
            { required: true, message: '请输入范围', trigger: 'blur' },
          ],
      },
      equipForm:{
        rateModel:9600,
        byteModel:8,
        portModel:'',
        stopModel:1,
        checkModel:'N',
        start:1,
        end:255
      },
      rate:[600,1200,2400,4800,9600,14400,19200,28800,38400,57600,115200,230400,460800],//波特率
      checkList:[
        {value: 'N',label: '无校验'},
        {value: 'E',label: '奇校验'},
        {value: 'O',label: '偶校验'},
        {value: '0',label: '0校验'},
        {value: '1',label: '1校验'}
      ],
      stopList:[
        {value: 1,label: '1位'},
        {value: 1.5,label: '1.5位'},
        {value: 2,label: '2位'}
      ],
      rateList:[2400,4800,9600,19200,38400,57600,115200],
      byteList:[7,8,9],
      portList:[],
      configName:'',
      editConfig:true,
      eid:0,
      ids:[],
      settingForm:{
        rate:1,
        eid:this.eid,
        autoUpload:true,
        background:true
      },
      loading:false,
      equipList:[],
      config:{},
      timer:null,
      loadingText:"搜索设备中",
      all:'1',
      chooseConfigName:"未选择配置",
      chooseSn:[],
      configList:[]
    }
  },
  computed:{
    filterConfigList(){
      return this.configList.filter(item=>Object.values(item).join('').indexOf(this.configName)!==-1);
    }
  },
  created(){
    this.getPortList();
    clearInterval(this.timer);
    this.timer = setInterval(()=>{
      this.getPortList();
    },2000)
    Bus.$on('duankai', () => {  
        this.config = {};
        this.equipList = [];
    });
  },
  beforeDestroy(){
    clearInterval(this.timer);
  },
  methods:{
    initConfig(){
      this.config = {
        "keyArr":[
          {"key_led":[0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0],"key_param":[1,0,5,0,0,82],"key_relay":[0,1,0,5,0,0,1,0,5,0,0,1,0,5,0,0,1,0,5,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[2,0,5,0,0,54],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[3,0,5,0,0,50],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[4,0,5,0,0,18],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[5,0,5,0,0,4],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[6,0,5,0,0,18],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[7,0,5,0,0,2],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},
          {"key_led":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key_param":[8,0,5,0,0,100],"key_relay":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
        ],
        "paramArr":[7175,1,2,1,1,0,65535,65535]
      };
      this.transformConfig(this.config);
      this.$forceUpdate();
    },
    confirmConfig(config){
      this.config = config;
      this.$forceUpdate();
    },
    transformConfig(config){
      config.keyArr.forEach(i=>{
        this.$set(i,'key_led_arr',this.groupArray(i.key_led,5));
        this.$set(i,'key_relay_arr',this.groupArray(i.key_relay,5));
        this.$set(i,'key_led_events',this.getEvents(i.key_led_arr,'LED控制'));
        this.$set(i,'key_relay_events',this.getEvents(i.key_relay_arr,'继电器控制'));
        this.$set(i,'key_code_arr',this.transformKeyCode(i.key_param[4]));
      })
      // console.log(config);
    },
    //不足8位前面补0
    preZero(val){
      let arr = []
      for(let i=0;i<8-val.length;i++){
          arr.push(0);
      }
      return arr.join("")+val
    },
    // 设备键号转换  0-255  0 => 000000000    100 => 01100100    3,6,7
    transformKeyCode(keyCode){
      let hex2String = keyCode.toString(2);
      let midString = this.preZero(hex2String);
      let arr = [];
      for(let i=0;i<8;i++){
        midString[7-i] === '1' && arr.push(i+1+'')
      }
      return arr;
    },
    // 设备键号反转换
    reverseTransformKeyCode(keyCodeArr){
      console.log('start key_code_arr',keyCodeArr);
      let midArr = ['0','0','0','0','0','0','0','0'];
      for(let i=0;i<8;i++){
        keyCodeArr.includes(i+1+'') && (midArr[i]='1');
      }
      const midString = midArr.reverse().join('');
      console.log('end key_code_arr',parseInt(midString,2));
      return parseInt(midString,2);
    },
    reverseTransformConfig(config){
      let tempConfig = JSON.parse(JSON.stringify(config));
      console.log('start config',tempConfig);
      tempConfig.keyArr.forEach(item=>{
        item.key_led_arr = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
        item.key_relay_arr = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
        console.log(item.key_led_arr);
        item.key_led_events.forEach((event,index)=>{
          event.labels.forEach(label=>{
            item.key_led_arr[label-1] = item.key_led_events[index].values;
          })
        })
        item.key_led = this.flatArray(item.key_led_arr);

        item.key_relay_events.forEach((event2,index2)=>{
          event2.labels.forEach(label=>{
            item.key_relay_arr[label-1] = item.key_relay_events[index2].values;
          })
        })
        item.key_relay = this.flatArray(item.key_relay_arr);
        // console.log(item.key_code_arr);
        item.key_param[4] = this.reverseTransformKeyCode(item.key_code_arr);
      })
      console.log('result config',tempConfig);
      return tempConfig;
    },
    //获取事件
    getEvents(ledArr,eventLabel){
      const emitEvent = eventLabel === 'LED控制' ? 0 : 1;
      let obj = {};
      let tempArr = [];
      ledArr.forEach((item,index)=>{
        if(item[1] !== 0){
          const tempArrString = JSON.stringify(item);
          if(obj.hasOwnProperty(tempArrString)){
            obj[tempArrString].push(index+1);
          } else {
            obj[tempArrString] = [index+1];
          }
        }
      })
      for(const i in obj){
        const labels = obj[i];
        const values = JSON.parse(i)
        const checkList = this.labels2CheckList(labels);
        const tempObj = {
          labels,
          values,
          eventLabel,
          checkList,
          emitEvent
        }
        tempArr.push(tempObj);
      }
      return tempArr;
    },
    labels2CheckList(labels){
      const checkList = [];
      for(let i=1;i<9;i++){
        if(labels.includes(i)){
          checkList.push('1');
        } else {
          checkList.push('0')
        }
      }
      return checkList;
    },
    //数组扁平化
    flatArray(array){
      const temp = [...array]
      return temp.reduce((result, item)=> {
          return result.concat(Array.isArray(item) ? this.flatArray(item) : item);
      }, []);
    },
    //分割数组
    groupArray(array, subGroupLength){
      let index = 0;
      let newArray = [];
      while(index < array.length) {
          newArray.push(array.slice(index, index += subGroupLength));
      }
      return newArray;
    },
    chooseEquips(ids){
      this.ids = ids;
    },
    changeConfig(item){
      this.chooseConfigName = item.name;
      this.editConfig = true;
      this.config = JSON.parse(item.config);
    },
    chooseConfig(){
      this.editConfig = false;
      this.getConfigList();
    },
    getConfigList(delFlag){
      delFlag && (this.chooseConfigName = '未选择配置');
      this.loading = true;
      let {all} = this;
      let params = {
        all
      }
      this.loadingText = "加载配置中...";
      this.$http.get("/config/list",params).then(res=>{
        this.configList = res.data;
        this.loading = false;
      }).catch(()=>{
        this.loading = false;
      })
    },
    getPortList(){
      this.$lhttp.get("/portlist").then(res=>{
          this.portList = res.data;
      })
    },
    downloadTo(eid,flag){
      if(!this.$store.state.User.status){
        this.$message({
          type: 'error',
          message: '请先搜索设备',
          showClose:true
        });
        return
      }
      if(!eid){
        this.$message({
          type: 'error',
          message: '请选择设备',
          showClose:true
        });
        return
      }
      let { config } = this;
      let newConfig = this.reverseTransformConfig(config);
      
      let params = {
        ...newConfig,eid
      }
      // console.log(params);
      // flag&&(params.paramArr[2] = eid);
      params.paramArr[1] = eid;
      this.loading = true;
      this.loadingText = "下载配置中..."
      this.$lhttp.post('/download_config',params).then(res=>{
        let msg = flag?"设备"+eid+":配置成功":"配置成功";
        this.$message({
          message:msg,
          type:"success",
          showClose:true
        });
        this.loading = false;
      }).catch(_=>{
        this.loading = false;
      })
    },
    downloadTos(){
      if(!this.$store.state.User.status){
        this.$message({
          message:"请先搜索设备",
          type:'error',
          showClose:true
        })
        return
      }
      console.log(this.ids);
      if(this.ids.length === 0){
        this.$message({
          message:"请选择设备",
          type:'error',
          showClose:true
        })
        return
      }
      if(JSON.stringify(this.config) === '{}'){
        this.$message({
          message:"请选择配置",
          type:'error',
          showClose:true
        })
        return
      }
      this.ids.forEach((item,index)=>{
        setTimeout(()=>{
          this.downloadTo(item,true);
        },500*index);
      })
    },
    delConfig({item,index,eventIndex}){
        this.$confirm('此操作将删除此配置, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            if(item.emitEvent === 0){
                this.config.keyArr[index].key_led_events.splice(eventIndex,1);
            } else {
                this.config.keyArr[index].key_relay_events.splice(eventIndex,1);
            }
            console.log(this.config);
            this.$message({
                type: 'success',
                message: '删除成功!',
                showClose:true
            });
        })
      },
    downloadConfig(){
      this.$prompt('请输入配置备注', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /\S/,
        inputErrorMessage: '请输入备注'
      }).then(({ value }) => {
        let config = JSON.stringify(this.config);
        if(config === "{}"){
          this.$message({
            showClose:true,
            message:"请先配置",
            type:"error"
          });
          return;
        }
        if(value === ""){
          this.$message({
            showClose:true,
            message:"请输入配置备注",
            type:"error"
          });
          return;
        }
        let name = value;
        const type = "x20";
        let params = {
          config,name,type
        }
        this.$http.post('/config/add',params).then(res=>{
          this.$message({
            message:"保存成功",
            type:"success",
            showClose:true
          });
        })
      })
    },
    chooseEquip({eid,sn}){
      this.chooseConfigName = "未选择配置";
      this.eid = eid;
      let params = {
        eid
      };
      this.chooseSn = sn;
      this.loading = true;
      this.loadingText = "查询配置中...";
      this.$lhttp.get('/equipconfig',params).then(res=>{
        this.config = res.data;
        this.transformConfig(this.config); //转换数组
        this.loading = false;
        this.editConfig = true;
      }).catch(_=>{
        this.loading = false;
      })
    },
    rulesValide(){
      this.$refs['searchForm'].validate((valid) => {
        if (valid) {
          this.searchEquips();
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    searchEquips(){
      if(this.equipForm.portModel === ""){
        this.$message({
          showClose:true,
          message:"请选择串口",
          type:"error",
          duration:100000
        });
        return;
      }
      this.loading = true;
      this.loadingText = "搜索设备中...";
      const data = JSON.parse(JSON.stringify(this.equipForm));
      data.end+=1;
      this.$lhttp.post("/equipinit",data).then(res=>{
          this.loading = false
          this.equipList = res.data;
          this.equipList.forEach((item)=>{
            this.$set(item,"checked",false)
          })
      }).catch(()=>{
        this.loading = false
      })
    }
  }
}
</script>

<style lang="scss" scoped>
  /deep/ .no-error-form .el-form-item{
    margin-bottom:0;
  }
  /deep/ .el-form-item{
    margin-bottom:18px;
  }
  .switch-page{
    display: flex;
    height:100%;
    padding:5px;
    background:white;
    box-sizing: border-box;
    .switch-left{
      width:20%;
      background: #FFFFFF;
      border-radius: 10px;
      border: 3px solid #F4F5FE;
    }
    .switch-right{
      flex:1;
      background: #FFFFFF;
      border-radius: 10px;
      border: 3px solid #F4F5FE;
      padding:.8rem;
      height:100%;
      overflow: auto;
    }
  }
</style>